package com.whynot.frame.manythread;

import java.util.LinkedList;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 模拟消息队列的阻塞性存取数据
 * @author Administrator
 *
 */
public class MyQueue {
	
	private LinkedList<String> linkedList = new LinkedList<String>();
	private AtomicInteger count = new AtomicInteger(0);
	final Object lock = new Object();
	
	private int maxSize;
	private int minSize;

	public MyQueue(int maxSize) {
		this.maxSize = maxSize;
	}
	
	/**
	 * 存数据
	 * @param str
	 */
	public void put(String str){
		try {
			synchronized (lock) {
				if(count.get() == maxSize){//当队列的最大限度已满
					lock.wait();//通知take，快点取元素
				}
				//队列数据未满
				linkedList.add(str);//添加元素
				count.incrementAndGet();//计数器加1
				lock.notify();//同时通知take，刚加入元素，可以取元素了
				System.out.println("新加入的元素是："+str);
			}
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	/**
	 * 取元素
	 * @return
	 */
	public String take(){
		String ret = "";
		try {
			synchronized (lock) {
				if(count.get() == minSize){//当队列的没有元素
					lock.wait();//通知put，快点存元素
				}
				//队列无数据
				ret = linkedList.removeFirst();
				count.decrementAndGet();//计数器减1
				lock.notify();//同时通知put，刚取完元素，可以加元素了
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		return ret;
	}
	
	public static void main(String[] args) {
		final MyQueue queue = new MyQueue(5);
		queue.put("a");
		queue.put("b");
		queue.put("c");
		queue.put("d");
		queue.put("e");
		
		Thread t1 = new Thread(new Runnable() {
			public void run() {
				while(true){//加上这个，就会是循环，连续不断的生产
					queue.put("f");
					queue.put("g");
				}
			}
		});
		
		t1.start();
		
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		Thread t2 = new Thread(new Runnable() {
			public void run() {
				while(true){//加上这个，就会是循环，连续不断的消费
					for (int i = 0; i < queue.maxSize; i++) {
						System.out.println("取出的对象"+queue.take());
					}
				}
			}
		});
		
		t2.start();
		
	}
	
	
}
